package com.tool.sqlexecutor.command;

import com.tool.sqlexecutor.config.ConfigCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.shell.Shell;
import org.springframework.shell.jline.InteractiveShellApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Optional;


@Component
@Order(InteractiveShellApplicationRunner.PRECEDENCE - 100) // Runs before InteractiveShellApplicationRunner
public class ScriptShellApplicationRunner implements ApplicationRunner {
    Logger logger = LoggerFactory.getLogger(ScriptShellApplicationRunner.class);
    private static final String PARAM_CONFIG = "config";
    private static final String DEFAULT_CONFIG_FILE = "config.json";
    private static final String PARAM_ENV = "env";
    private static final String PARAM_SCRIPT = "script";
    private static final String USER_DIR = "user.dir";
    private final ConfigurableEnvironment environment;
    private final Shell shell;

    public ScriptShellApplicationRunner(Shell shell, ConfigurableEnvironment environment) {
        this.environment = environment;
        this.shell = shell;
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.info("Working directory=" + System.getProperty(USER_DIR));
        File file = getConfig(args);
        if (file == null) {
            file = getFile(DEFAULT_CONFIG_FILE);
        }
        if (file == null) {
            return;
        }
        new ConfigCommands().reset(file);

        Optional<String> env = getEnv(args);
        if (!env.isPresent()) {
            return;
        }
        logger.info(" env=" + env.get());

        Optional<File> script = getScript(args);
        if (!script.isPresent()) {
            return;
        }
        logger.info(" script=" + script.get().getAbsolutePath());

        String result = new SqlCommands().run(env.get(), -1, null, script.get(), null);
        logger.info(result);
        InteractiveShellApplicationRunner.disable(environment);
    }

    private File getConfig(ApplicationArguments args) {
        if (!args.containsOption(PARAM_CONFIG)) {
            return null;
        }
        String fileName = args.getOptionValues(PARAM_CONFIG).get(0);
        return getFile(fileName);
    }

    private File getFile(String fileName) {
        File file = new File(fileName);
        if (file.exists() && file.isFile()) {
            return file;
        }
        logger.info(file.getAbsolutePath() + " is not a file");
        file = new File(System.getProperty(USER_DIR) + "/" + fileName);
        if (file.exists() && file.isFile()) {
            return file;
        }
        logger.info(file.getAbsolutePath() + " is not a file");
        return null;
    }

    private Optional<String> getEnv(ApplicationArguments args) {
        if (!args.containsOption(PARAM_ENV)) {
            return Optional.empty();
        }
        String env = args.getOptionValues(PARAM_ENV).get(0);
        return Optional.of(env);
    }

    private Optional<File> getScript(ApplicationArguments args) {
        if (!args.containsOption(PARAM_SCRIPT)) {
            return Optional.empty();
        }
        String fileName = args.getOptionValues(PARAM_SCRIPT).get(0);
        return Optional.ofNullable(getFile(fileName));
    }
}
